// @Author EthanScriptOn
// @Desc
package dao

import (
	"fmt"
	"gitee.com/fatzeng/srf_switch_dynamic_logic_director/config"
	"gitee.com/fatzeng/srf_switch_dynamic_logic_director/dto"
	"gitee.com/fatzeng/srf_switch_dynamic_logic_director/pojo"
	"gitee.com/fatzeng/srf_switch_dynamic_logic_director/request"
	"github.com/go-xorm/xorm"
)

func SwitchRuleDetailList(param *request.SwitchOptionDetailRequest) (result []*pojo.SrfSwitchPublishLogGroup, count int64, err error) {
	engine := config.GetMysqlEngine()
	session := engine.NewSession()
	session = session.Table("srf_switch_publish_log").Alias("s1").Join("LEFT OUTER", []string{"srf_switch_option_log", "s2"}, "s1.option_id = s2.id")
	count, err = session.Where("env = ? and group = ? and namespace = ? and switch_name = ?", param.Env, param.Group, param.Namespace, param.SwitchName).Limit(param.GetLimit(), param.GetStart()).OrderBy("s2.created_at desc").FindAndCount(&result)
	if err != nil {
		return nil, 0, fmt.Errorf("error finding data: %v", err)
	}
	return
}

func SwitchRuleList(param *request.SwitchListRequest) (result []*pojo.SrfSwitchPublishLog, count int64, err error) {
	engine := config.GetMysqlEngine()
	session := engine.NewSession()
	if param.Env != "" {
		session = session.Where("env = ?", param.Env)
	}
	if param.Group != "" {
		session = session.Where("group = ?", param.Group)
	}
	if param.Namespace != "" {
		session = session.Where("namespace = ?", param.Namespace)
	}
	if param.SwitchName != "" {
		session = session.Where("switch_name = ?", param.SwitchName)
	}
	count, err = session.Limit(param.GetLimit(), param.GetStart()).Desc("created_at").FindAndCount(&result)
	if err != nil {
		return nil, 0, fmt.Errorf("error finding data: %v", err)
	}
	return
}

func SessionRollBack(optionError error, session *xorm.Session) error {
	rollBackErr := session.Rollback()
	if rollBackErr != nil {
		return fmt.Errorf("error operation data: %v ,error rollback transaction: %v", optionError, rollBackErr)
	}
	return optionError
}

func SwitchPublish(switchBody *dto.SwitchBody) (err error) {
	engine := config.GetMysqlEngine()
	session := engine.NewSession()
	defer session.Close()
	optionLog := new(pojo.SrfSwitchOptionLog)
	optionLog.SwitchRemark = switchBody.SwitchRemark
	optionLog.CreatedAt = switchBody.CreatedAt
	optionLog.OperatorUserId = switchBody.OperatorUserId
	err = InsertSwitchRuleOptionLog(session, optionLog)
	if err != nil {
		return SessionRollBack(err, session)
	}

	if optionLog.Id == 0 {
		return SessionRollBack(fmt.Errorf("unable to obtain operation record ID"), session)
	}

	publishLog := new(pojo.SrfSwitchPublishLog)
	publishLog.SwitchName = switchBody.SwitchName
	publishLog.OptionId = optionLog.Id
	publishLog.CreatedAt = switchBody.CreatedAt
	publishLog.Env = switchBody.Env
	publishLog.Group = switchBody.Group
	publishLog.Namespace = switchBody.Namespace
	err = InsertSwitchRuleLog(session, publishLog)
	if err != nil {
		return SessionRollBack(err, session)
	}

	publishFunction := config.GetSrfSwitchPublishFunction()
	err = publishFunction(publishLog)
	if err != nil {
		return SessionRollBack(err, session)
	}

	if err = session.Commit(); err != nil {
		return err
	}

	return
}

func InsertSwitchRuleLog(session *xorm.Session, param *pojo.SrfSwitchPublishLog) (err error) {
	if _, err = session.Insert(param); err != nil {
		return fmt.Errorf("error inserting switch rule log data: %v", err)
	}
	return
}

func InsertSwitchRuleOptionLog(session *xorm.Session, param *pojo.SrfSwitchOptionLog) (err error) {
	if _, err = session.Insert(param); err != nil {
		return fmt.Errorf("error inserting switch rule option log data: %v", err)
	}
	return
}
